package org.jpro.config;

import java.util.Properties;

import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;

import com.atomikos.icatch.config.UserTransactionService;
import com.atomikos.icatch.config.UserTransactionServiceImp;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;

/**
 * <P>功能描述 : JTA事物 </P>
 * <P>File name : JTAConfig </P>
 * <P>Author : 王泽浩 </P>
 * <P>E-Mail : 1028625100@qq.com </P>
 * <P>Date : 2017/3/1 下午10:00</P>
 */
@Configuration
@ComponentScan
@EnableTransactionManagement
public class JTAConfig {

    /**
     * 超时时间
     */
    private final int transactionTimeout = 300;

    @Bean("userTransactionService")
    public UserTransactionService userTransactionService() {
        Properties properties = new Properties();
        properties.setProperty("com.atomikos.icatch.service", "com.atomikos.icatch.standalone.UserTransactionServiceFactory");
        return new UserTransactionServiceImp(properties);
    }

    @Bean(name = "userTransaction")
    @DependsOn("userTransactionService")
    public UserTransaction userTransaction() throws Throwable {
        UserTransactionImp userTransactionImp = new UserTransactionImp();
        userTransactionImp.setTransactionTimeout(transactionTimeout);
        return userTransactionImp;
    }

    @DependsOn("userTransactionService")
    @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
    public TransactionManager atomikosTransactionManager() throws Throwable {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setForceShutdown(false);
        return userTransactionManager;
    }

    @Primary
    @Bean(name = "transactionManager")
    @DependsOn({ "userTransactionService", "userTransaction", "atomikosTransactionManager" })
    public PlatformTransactionManager transactionManager(@Qualifier("userTransaction") UserTransaction userTransaction,
            @Qualifier("atomikosTransactionManager") TransactionManager transactionManager) throws Throwable {
        JtaTransactionManager manager = new JtaTransactionManager(userTransaction, transactionManager);
        manager.setAllowCustomIsolationLevels(true);
        return manager;
    }

}
